import mountNativeElement from './mountNativeElement';
import { isFunction, isFuntionComponent } from './utils/index';

// 处理组件vDom
export default function mountComponent(vDom, container, oldDom) {
  let nextVDom = null;
  let component = null; // 如果是处理类组件 用这个记录类组件的实例对象
  // 判断这个组件是类组件还是函数组件
  if (isFuntionComponent(vDom)) {
    // 函数组件
    nextVDom = buildFunctionComponent(vDom);
  } else {
    // 类组件
    nextVDom = buildClassComponent(vDom);
    component = nextVDom.component;
  }

  if (isFunction(nextVDom)) { // 如果组件的 vDom 还是一个组件
    // 比如：function Demo() {return <Others />}
    mountComponent(nextVDom, container, oldDom); // 再次调用 mountComponent
  } else {
    mountNativeElement(nextVDom, container, oldDom);
  }

  // 执行到这里如果有类组件的实例对象 说明是类组件，那么看类的 props 上有没有ref 如果有 把实例对象当做参数传给ref函数
  if (component) {
    component.componentDidMount(); // componentDidMount 执行
    if (component.props && component.props.ref) {
      component.props.ref(component);
    }
  }

}

function buildFunctionComponent(vDom) { // 处理函数组件
  return vDom.type(vDom.props || {});
}

function buildClassComponent(vDom) { // 处理类对象
  const component = new vDom.type(vDom.props || {}); // 实例化组件的构造函数
  const nextVDom = component.render(); // 得到组件 render 函数返回的vDom
  nextVDom.component = component; // 将实例对象绑定到虚拟dom属性中
  return nextVDom;
}
